package org.jeecg.glr.util;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.time.DateUtils;

public class DcDateUtils extends DateUtils
{
    /** yyyy-MM-dd. */
    public static final String FORMAT_YMD_1 = "yyyy-MM-dd";

    /** yyyy/MM/dd. */
    public static final String FORMAT_YMD_2 = "yyyy/MM/dd";

    /** yyyyMMdd. */
    public static final String FORMAT_YMD_3 = "yyyyMMdd";

    /** yy/MM/dd. */
    public static final String FORMAT_YMD_4 = "yy/MM/dd";

    /** yyyy/M/d. */
    public static final String FORMAT_YMD_5 = "yyyy/M/d";

    /** yyMMdd. */
    public static final String FORMAT_YMD_6 = "yyMMdd";

    /** yyyy.MM.dd. */
    public static final String FORMAT_YMD_7 = "yyyy.MM.dd";

    /** yyyyMM. */
    public static final String FORMAT_YM_1 = "yyyyMM";

    /** yyyy/MM. */
    public static final String FORMAT_YM_2 = "yyyy/MM";

    /** yyyy-MM-dd HH:mm:ss. */
    public static final String FORMAT_DATE_TIME_1 = "yyyy-MM-dd HH:mm:ss";

    /** yyyy/MM/dd HH:mm:ss. */
    public static final String FORMAT_DATE_TIME_2 = "yyyy/MM/dd HH:mm:ss";

    /** yyyyMMddHHmmss. */
    public static final String FORMAT_DATE_TIME_3 = "yyyyMMddHHmmss";

    /** yyyy-MM-dd HH:mm. */
    public static final String FORMAT_DATE_TIME_4 = "yyyy-MM-dd HH:mm";

    /** yyyy/MM/dd HH:mm. */
    public static final String FORMAT_DATE_TIME_5 = "yyyy/MM/dd HH:mm";

    /** yyyy-MM-dd HH:mm:ss.SSS. */
    public static final String FORMAT_DATE_TIME_7 = "yyyy-MM-dd HH:mm:ss.SSS";

    /** yyyyMMddHHmm. */
    public static final String FORMAT_DATE_TIME_8 = "yyyyMMddHHmm";

    /** yyyyMMddHHmmssSSS. */
    public static final String FORMAT_DATE_TIME_9 = "yyyyMMddHHmmssSSS";

    /** yyyy. */
    public static final String FORMAT_YEAR_1 = "yyyy";

    /** MM. */
    public static final String FORMAT_MONTH_1 = "MM";

    /** HH:mm:ss. */
    public static final String FORMAT_TIME_1 = "HH:mm:ss";

    /** HH:mm. */
    public static final String FORMAT_HM_1 = "HH:mm";

    /** HHmm. */
    public static final String FORMAT_HM_2 = "HHmm";

    /** HHmmss. */
    public static final String FORMAT_HM_3 = "HHmmss";

    /** dd. */
    public static final String FORMAT_DATE_1 = "dd";

    /** HH. */
    public static final String FORMAT_HOUR_1 = "HH";

    /** mm:ss. */
    public static final String FORMAT_MS_1 = "mm:ss";

    /** mmss. */
    public static final String FORMAT_MS_2 = "mmss";

    private DcDateUtils()
    {}

    /**
     * 获取给定日期月的最后一天。
     *
     * @param date
     *            日期
     * @return int 最后一天的日期值
     */
    public static int getLastDayOfMonth(Date date)
    {

        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        return calender.getActualMaximum(DateField.DAY_OF_WEEK.value());
    }

    /**
     * 取得给定日期，在指定字段上的值。
     *
     * @param date
     *            日期
     * @param field
     *            日期字段类型
     * @return int 值
     */
    public static int getField(Date date, DateField field)
    {

        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        return calender.get(field.value());
    }

    /**
     * 将日期从一种格式转为另外一种格式。
     *
     * @param strDate
     *            日期
     * @param formatFrom
     *            原格式
     * @param formatTo
     *            目标格式
     * @return String 转换后的日期
     * @throws ParseException
     */
    public static String formatDate(String strDate, String formatFrom, String formatTo) throws ParseException
    {
        if(StringUtil.isEmpty(strDate))
        {
            return strDate;
        }
        SimpleDateFormat ff = new SimpleDateFormat(formatFrom);
        ff.setLenient(false);

        SimpleDateFormat ft = new SimpleDateFormat(formatTo);
        ft.setLenient(false);

        return ft.format(ff.parse(strDate));

    }

    /**
     * 将字符串日期按指定格式，转换为日期类型。
     *
     * @param date
     *            字符串日期
     * @param strFormat
     *            目标日期格式
     * @return Date 日期
     */
    public static Date toDate(String date, String strFormat)
    {
        if(StringUtil.isEmpty(date))
        {
            return null;
        }
        try
        {
            SimpleDateFormat df = new SimpleDateFormat(strFormat);
            df.setLenient(false);
            Date objDate = df.parse(date);
            return objDate;
        }
        catch (Exception e)
        {
            return null;
        }
    }

    /**
     * 将日期（Date类型），按照指定的格式，转换为另一种日期格式
     *
     * @param date
     *            日期
     * @param strFormat
     *            目标日期格式
     * @return Date 日期
     */
    public static Date toDate(Date date, String strFormat)
    {
        if(date == null)
        {
            date = DcDateUtils.now();
        }
        if(!StringUtil.isEmpty(strFormat))
        {
            date = DcDateUtils.toDate(DcDateUtils.toString(date, strFormat), strFormat);
        }
        return date;
    }

    /**
     * 将日期（Date类型），按照指定的格式，转换为字符串日期。
     *
     * @param date
     *            日期
     * @param toFormat
     *            目标格式
     * @return String 字符串日期
     */
    public static String toString(Date date, String toFormat)
    {
        if(date == null)
        {
            return "";
        }
        SimpleDateFormat df = new SimpleDateFormat(toFormat);
        df.setLenient(false);
        return df.format(date);
    }

    /**
     * 将日期（Date类型），按照指定的格式，转换为字符串日期。
     *
     * @param date
     *            日期
     * @param toFormat
     *            目标格式
     * @return String 字符串日期
     */
    public static String toString(Date date, String[] toFormats)
    {
        if(date == null)
        {
            return "";
        }
        String dateStr = null;
        for (String toFormat : toFormats)
        {
            SimpleDateFormat df = new SimpleDateFormat(toFormat);
            df.setLenient(false);
            dateStr = df.format(date);
            if(!StringUtil.isEmpty(dateStr))
            {
                return dateStr;
            }
        }
        return null;
    }

    /**
     * 计算开始日期到结束日期，在指定日期字段上的差值。
     *
     * @param begin
     *            开始日期
     * @param end
     *            结束日期
     * @param field
     *            日期字段
     * @return long 日期差值
     */
    public static long difference(Date begin, Date end, DateField field)
    {
        return field.difference(begin, end);
    }

    /**
     * 在日期的指定日期字段上，进行加减操作。
     *
     * @param date
     *            日期
     * @param field
     *            日期字段
     * @param amount
     *            加减操作的值
     * @return Date 处理后的日期
     */
    public static Date add(Date date, DateField field, int amount)
    {

        Calendar calender = Calendar.getInstance();
        calender.setTime(date);

        calender.add(field.value(), amount);
        return calender.getTime();
    }

    /**
     * 当前时间。
     *
     * @return Date
     */
    public static Date now()
    {
        return Calendar.getInstance().getTime();
    }

    /**
     * 将目标日期设置到0点。
     *
     * @param target
     *            目标日期
     * @return Date
     */
    public static Date setToZero(Date target)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(target.getTime());
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 将目标日期设置到午夜23点59分59秒。
     *
     * @param target
     *            目标日期
     * @return Date
     */
    public static Date setToNight(Date target)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(target.getTime());
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }

    /**
     * 将目标日期加一天。
     *
     * @param target
     *            目标日期
     * @return Date
     */
    public static Date addDay(Date target)
    {
        return modifyDay(target, 1);
    }

    /**
     * 将目标日期加days天。
     *
     * @param target
     *            目标日期
     * @param days
     *            增加的天数
     * @return Date
     */
    public static Date addDay(Date target, int days)
    {
        return modifyDay(target, days);
    }

    /**
     * 将目标日期减一天。
     *
     * @param target
     *            目标日期
     * @return Date
     */
    public static Date minusDay(Date target)
    {
        return modifyDay(target, -1);
    }

    /**
     * 将目标日期减少days天。
     *
     * @param target
     *            目标日期
     * @param days
     *            减少的天数（绝对值）
     * @return Date
     */
    public static Date minusDay(Date target, int days)
    {
        return modifyDay(target, -days);
    }

    /**
     * 取得当前天日期，并指定时、分、秒
     *
     * @param hours
     *            时
     * @param minutes
     *            分
     * @param seconds
     *            秒
     * @return Date
     */
    public static Date getTimeByInt(int hours, int minutes, int seconds)
    {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, hours);
        cal.set(Calendar.MINUTE, minutes);
        cal.set(Calendar.SECOND, seconds);
        return cal.getTime();
    }

    //调整日期天数
    private static Date modifyDay(Date target, int days)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(target.getTime());
        cal.add(Calendar.DATE, days);
        return cal.getTime();
    }

    /**
     * <p>
     * 根据给定的月份,对当前月份进行加减操作
     * </p>
     *
     * @param target
     * @param months
     *            需要变动的月份数
     * @return
     * @update: [updatedate] [changer][change description]
     */
    public static Date modifyMonth(Date target, int months)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(target.getTime());
        cal.add(Calendar.MONTH, months);
        return cal.getTime();
    }

    /**
     * <P>
     * 把秒转为小时分钟秒格式
     * </P>
     *
     * @param t
     *            毫秒
     * @return
     */
    public static String getTimeHMS(Long t)
    {
        int h = Integer.parseInt(String.valueOf(t / DcDateUtils.MILLIS_PER_HOUR));
        int m = Integer
                .parseInt(String.valueOf((t - (h * DcDateUtils.MILLIS_PER_HOUR)) / DcDateUtils.MILLIS_PER_MINUTE));
        int s = Integer
                .parseInt(String.valueOf((t - (h * DcDateUtils.MILLIS_PER_HOUR) - m * DcDateUtils.MILLIS_PER_MINUTE)
                        / DcDateUtils.MILLIS_PER_SECOND));

        String _h = h < 10 ? "0" + String.valueOf(h) : String.valueOf(h);
        String _m = m < 10 ? "0" + String.valueOf(m) : String.valueOf(m);
        String _s = s < 10 ? "0" + String.valueOf(s) : String.valueOf(s);
        String result = _h + ":" + _m + ":" + _s;
        return result;
    }

    public static void main(String[] args)
    {
        String date1 = DcDateUtils.toString(Calendar.getInstance().getTime(), FORMAT_YMD_1);
        Date date = DcDateUtils.toDate(date1 + " 12:00", FORMAT_DATE_TIME_4);
        //System.out.println(DcDateUtils.toString(date, FORMAT_DATE_TIME_4));
    }

}
